<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //bind创建一个新的函数，在bind被调用时，这个新函数的this被指定为bind的第一个参数，而其余参数将作为新函数的参数，供调用时使用
      // const module = {
      //   x: 42,
      //   getX: function () {
      //     return this.x //这里的this.x指的是x:42的参数
      //   },
      // }
      // const unboundGetx = module.getX //调用module.getX
      // console.log(unboundGetx()) //函数在全局范围内被调用，输出undefined
      // const boundGetx = unboundGetx.bind(module) //调用整个函数
      // console.log(boundGetx()) //输出42

      this.x = 9 //在浏览器中，this指向全局的"window"对象
      var module = {
        //函数作用域
        x: 81,
        getX: function () {
          return this.x
        },
      }
      module.getX() //输出81
      console.log(module.getX())

      var retrieveX = module.getX
      retrieveX()
      console.log(retrieveX()) //输出9，因为函数是在全局作用域中调用的
      var boundGetx = retrieveX.bind(module) //绑定module，调用this.x
      boundGetx()
      console.log(boundGetx())

      //偏函数:bind()的另一个最简单的用法是使一个函数拥有预设的初始函数，只要将这些参数(如果有)作为bind()的参数写在this后面，当绑定函数被调用时，这些参数会被插入参数列表的开始位置，传递给绑定函数的参数，会跟在它们的后面
      // function list() {
      //   return Array.prototype.slice.call(arguments)
      // }
      // function addArguments(arg1, arg2) {
      //   return arg1 + arg2
      // }

      // var list1 = list(1, 2, 3) //调用list函数
      // var result1 = addArguments(1, 2) //调用arguments函数，return 1+2
      // console.log(result1) //输出3
      // //创建一个函数，它拥有预设参数列表
      // var leading = list.bind(null, 37)
      // var add = addArguments.bind(null, 36)
      // //在调用leading变量时后面加上参数，就可以把37放在开始的位置
      // var list2 = leading(123, 123, 456)
      // console.log(list2)

      // var list3 = leading(1, 2, 3)
      // console.log(list3)

      // var result2 = add(5)
      // console.log(result2)

      // var result3 = add(10, 5)
      // console.log(result3)

      //作为构造函数使用的绑定函数
      //绑定函数自动适应于使用new操作符去构造一个由目标函数创建的新实例。当一个绑定函数是用来构建一个值的，原来提供的this就会被忽略，不过提供的参数列表仍然会插入到构造函数调用时的参数列表之前
      function Point(x, y) {
        this.x = x
        this.y = y
      }

      Point.prototype.toString = function () {
        return this.x + ',' + this.y
      }
      let p = new Point(1, 2)
      p.toString()
      console.log(p)

      let emptyObj = {}
      let YaxisPoint = Point.bind(emptyObj, 0)
    </script>
  </body>
</html>
